package com.yanfan.maintain.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.yanfan.attach.domain.DeviceDetail;
import com.yanfan.attach.mapper.DeviceDetailMapper;
import com.yanfan.common.core.domain.AjaxResult;
import com.yanfan.common.core.domain.entity.SysUser;
import com.yanfan.common.utils.SecurityUtils;
import com.yanfan.energy.domain.*;
import com.yanfan.energy.domain.enums.DeviceManageEnums;
import com.yanfan.energy.domain.model.ComboBoxBody;
import com.yanfan.energy.domain.statist.DateStatistics;
import com.yanfan.energy.domain.statist.RangeStatistics;
import com.yanfan.energy.mapper.*;
import com.yanfan.energy.service.ExcelService;
import com.yanfan.energy.util.DateUtils;
import com.yanfan.energy.util.SerialNumberUtil;
import com.yanfan.energy.util.WidgetUtil;
import com.yanfan.maintain.domain.*;
import com.yanfan.maintain.mapper.*;
import com.yanfan.maintain.service.InspectionService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;


/**
 * @author caijinkang
 * @date 2023年03月09日 15:12
 */
@Service("InspectionServiceImpl")
@Transactional(rollbackFor = Exception.class)
public class InspectionServiceImpl implements InspectionService {

    public static final String DAY = "day";
    public static final String WEEK = "week";
    public static final String MONTH = "month";

    @Resource
    private InspectionRouteDao inspectionRouteDao;
    @Resource
    private ClockingRouteDao clockingRouteDao;
    @Resource
    private InspectionPlanDao inspectionPlanDao;
    @Resource
    private InspectionTaskDao inspectionTaskDao;
    @Resource
    private ClockingRouteMiddleDao clockingRouteMiddleDao;
    @Resource
    private ClockingRouteCheckDao clockingRouteCheckDao;

    @Autowired
    private ExcelService excelService;
    @Resource
    private InspectionRouteMiddleDao inspectionRouteMiddleDao;
    @Autowired
    private DeviceDetailMapper deviceDetailMapper;
    @Autowired
    private ImageUrlDao imageUrlDao;
    @Autowired
    private InspectionTaskRouteLogMapper inspectionTaskRouteLogMapper;

    @Override
    public AjaxResult findTaskRecord(InspectionTask inspectionTask) {
        return AjaxResult.success(new PageInfo<>(inspectionTaskDao.findTaskRecord(inspectionTask)));
    }

    @Override
    public AjaxResult findPlanRecord(InspectionPlan inspectionPlan) {
        PageHelper.startPage(inspectionPlan.getPageNum(), inspectionPlan.getPageSize());
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 租户权限
        if (user.isAdmin()) {
            return AjaxResult.success(new PageInfo<>(inspectionTaskDao.findPlanRecord(inspectionPlan)));
        }
        return AjaxResult.success(new PageInfo<>(inspectionTaskDao.findPlanRecord(inspectionPlan)));
    }

    @Override
    public AjaxResult findInspectionRoute(InspectionBody inspectionBody) {
        if (inspectionBody.getCurrPage() != null || inspectionBody.getPageSize() != null) {
            PageHelper.startPage(inspectionBody.getCurrPage(), inspectionBody.getPageSize());
        }
        List<InspectionRoute> result = inspectionRouteDao.findInspectionRoute(inspectionBody.getName(), inspectionBody.getNumber());
        if (result != null && result.size() > 0) {
            return AjaxResult.success(new PageInfo<>(result));
        }
        return AjaxResult.error("查询失败");
    }

    @Override
    public AjaxResult findClockingRoute() {
        List<ComboBoxBody> result = clockingRouteDao
                .findClockingRoute()
                .stream()
                .map(c -> new ComboBoxBody(c.getId().intValue(), c.getName()))
                .collect(Collectors.toList());
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.error("查询失败");
    }

    @Override
    public AjaxResult findClockingRouteCheck() {
        List<ComboBoxBody> result = inspectionPlanDao.findClockingRouteCheck();
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.error("查询失败");
    }

    @Override
    public AjaxResult addInspectionRoute(InspectionRoute inspectionRoute) {
        if (!Objects.isNull(inspectionRoute)) {
            inspectionRoute.setCreatedBy(SecurityUtils.getUsername());
            int i = inspectionRouteDao.insert(inspectionRoute);
            if (!Objects.isNull(inspectionRoute.getRouteList())) {
                AtomicInteger a = new AtomicInteger(1);
                inspectionRoute.getRouteList().stream().forEach(r -> {
                    int add = inspectionRouteMiddleDao.insert(new InspectionRouteMiddle(null, inspectionRoute.getId(), null, SecurityUtils.getUsername(), null, null, a.get(), r.getDeviceId()));
                    a.getAndIncrement();
                });
            }
            if (i > 0) {
                return AjaxResult.success("新增成功");
            }
        }
        return AjaxResult.error("新增失败");
    }

    @Override
    public AjaxResult updateInspectionRoute(InspectionRoute inspectionRoute) {
        if (Objects.isNull(inspectionRoute)) {
            return AjaxResult.error("入参为空");
        }
        if (!Objects.isNull(inspectionRoute)) {
            // 根据路线Id删除中间表信息
            int del = inspectionRouteMiddleDao.deleteByRouteId(inspectionRoute.getId());
            AtomicInteger a = new AtomicInteger(1);
            // 重新遍历添加路线项
            inspectionRoute.getRouteList().stream().forEach(r -> {
                InspectionRouteMiddle inspectionRouteMiddle = new InspectionRouteMiddle(null, inspectionRoute.getId(), r
                        .getDeviceId()
                        .longValue(), SecurityUtils.getUsername(), null, null, a.get(), r.getDeviceId());
                int add = inspectionRouteMiddleDao.insert(inspectionRouteMiddle);
                a.getAndIncrement();
            });
        }
        int i = inspectionRouteDao.update(inspectionRoute);
        if (i > 0) {
            return AjaxResult.success("更新成功");
        }
        return AjaxResult.error("更新失败");
    }

    @Override
    public AjaxResult deleteInspectionRoute(Integer id) {
        int i = inspectionRouteDao.deleteById(id.longValue());
        // 根据路线Id删除中间表信息
        int del = inspectionRouteMiddleDao.deleteByRouteId(id.longValue());
        if (i > 0) {
            return AjaxResult.success("删除成功");
        }
        return AjaxResult.error("删除失败");
    }

    @Override
    public AjaxResult findInspectionPlan(InspectionPlanBody inspectionPlanBody) {
        List<InspectionPlan> result = inspectionPlanDao.findInspectionPlan(inspectionPlanBody.getNumber(), inspectionPlanBody.getName(), inspectionPlanBody.getRule(), inspectionPlanBody.getTotal(), inspectionPlanBody.isRegular());
        if (result != null && result.size() > 0) {
            result.stream().forEach(r -> {
                /*r.getRouteLists().stream().forEach(l -> {
                    List<CheckListBody> checkList = inspectionPlanDao.findCheckList(l.getId(), r.getId().intValue());
                    if (!Objects.isNull(checkList)) {
                        l.setCheckList(checkList);
                    }
                });*/
                if (r.getRegular() == 0) {
                    r.setRegularName("临时巡检");
                }
                if (r.getRegular() == 1) {
                    r.setRegularName("定期巡检");
                }
                if (r.getRule() == 1) {
                    r.setRuleName("时");
                }
                if (r.getRule() == 2) {
                    r.setRuleName("周");
                }
                if (r.getRule() == 3) {
                    r.setRuleName("日");
                }
            });
            PageInfo pageInfo = new PageInfo<>(result
                                                       .stream()
                                                       .skip((inspectionPlanBody.getCurrPage() - 1) * inspectionPlanBody.getPageSize())
                                                       .limit(inspectionPlanBody.getPageSize())
                                                       .collect(Collectors.toList()));
            return AjaxResult.success(pageInfo);
        }
        return AjaxResult.success(new PageInfo<>(result));
    }

    @Override
    public AjaxResult findInspectionPlanTwo(InspectionPlanBody inspectionPlanBody) {
        List<InspectionPlan> result = inspectionPlanDao.findAllInspectionPlan(inspectionPlanBody.getId());
        if (result != null && result.size() > 0) {
            result.stream().forEach(r -> {
                r.getRouteLists().stream().forEach(l -> {
                    /*List<CheckListBody> checkList = inspectionPlanDao.findCheckList(l.getId(), r.getId().intValue());
                    l.setCheckList(checkList);

                    if (!checkList.isEmpty()) {
                        //任务详情列表
                        checkList.stream().forEach(ch -> {
                            if (Objects.isNull(l.getId())) {
                                ch.setId(l.getId());
                            }
                        });
                        r.setCheckListBodies(checkList);
                    }*/

                });
            });
            return AjaxResult.success(result);
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findInspectionRule() {
        List<ComboBoxBody> result = new ArrayList<>();
        result.add(new ComboBoxBody(1, "时"));
        result.add(new ComboBoxBody(2, "周"));
        result.add(new ComboBoxBody(3, "日"));
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.error("查询失败");
    }

    @Override
    @Transactional
    public AjaxResult addInspectionPlan(InspectionPlan inspectionPlan) {
        if (!Objects.isNull(inspectionPlan)) {
            inspectionPlan.setCreatedBy(SecurityUtils.getUsername());
            int i = inspectionPlanDao.insert(inspectionPlan);

            if (!Objects.isNull(inspectionPlan.getRouteLists())) {
                inspectionPlan.getRouteLists().stream().forEach(rou -> {

                    if (!Objects.isNull(rou.getCheckList())) {
                        rou.getCheckList().stream().forEach(che -> {
                            // 根据路线id和计划id删除检查项
                            int del = clockingRouteMiddleDao.deleteByPlanIdAndRouteId(inspectionPlan
                                                                                              .getId()
                                                                                              .intValue(), rou.getId());

                            int sel = clockingRouteCheckDao.findClockingRouteByName(che.getName());
                            // 已存在检查项
                            if (sel > 0) {
                                // 添加检查项关联
                                int add = clockingRouteMiddleDao.insert(new ClockingRouteMiddle(null, rou
                                        .getId()
                                        .longValue(), inspectionPlan.getId(), che.getId(), null, SecurityUtils.getUsername(), null, null));
                            }
                            // 自定义检查项
                            if (sel <= 0) {
                                // 添加自定义检查项
                                ClockingRouteCheck clockingRouteCheck = new ClockingRouteCheck(null, che.getName(), 1, null, SecurityUtils.getUsername(), null, null);
                                clockingRouteCheckDao.insert(clockingRouteCheck);

                                // 添加检查项关联
                                int add = clockingRouteMiddleDao.insert(new ClockingRouteMiddle(null, rou
                                        .getId()
                                        .longValue(), inspectionPlan.getId(), clockingRouteCheck
                                                                                                        .getId()
                                                                                                        .intValue(), null, SecurityUtils.getUsername(), null, null));
                            }

                        });
                    }

                });
            }

            if (i > 0) {
                return AjaxResult.success("新增成功");
            }
        }
        return AjaxResult.error("新增失败");
    }

    @Override
    @Transactional
    public AjaxResult updateInspectionPlan(InspectionPlan inspectionPlan) {
        if (Objects.isNull(inspectionPlan)) {
            return AjaxResult.error("入参为空");
        }
        if (!Objects.isNull(inspectionPlan)) {
            inspectionPlan.getRouteLists().stream().forEach(rou -> {

                if (!Objects.isNull(rou.getCheckList())) {
                    rou.getCheckList().stream().forEach(che -> {
                        // 根据路线id和计划id删除检查项
                        int del = clockingRouteMiddleDao.deleteByPlanIdAndRouteId(inspectionPlan
                                                                                          .getId()
                                                                                          .intValue(), rou.getId());

                        int sel = clockingRouteCheckDao.findClockingRouteByName(che.getName());
                        // 已存在检查项
                        if (sel > 0) {
                            // 添加检查项关联
                            int add = clockingRouteMiddleDao.insert(new ClockingRouteMiddle(null, rou
                                    .getId()
                                    .longValue(), inspectionPlan.getId(), che.getId(), null, SecurityUtils.getUsername(), null, null));
                        }
                        // 自定义检查项
                        if (sel <= 0) {
                            // 添加自定义检查项
                            ClockingRouteCheck clockingRouteCheck = new ClockingRouteCheck(null, che.getName(), 1, null, SecurityUtils.getUsername(), null, null);
                            clockingRouteCheckDao.insert(clockingRouteCheck);

                            // 添加检查项关联
                            int add = clockingRouteMiddleDao.insert(new ClockingRouteMiddle(null, rou
                                    .getId()
                                    .longValue(), inspectionPlan.getId(), clockingRouteCheck
                                                                                                    .getId()
                                                                                                    .intValue(), null, SecurityUtils.getUsername(), null, null));
                        }

                    });
                }

            });
        }

        int f = inspectionPlanDao.update(inspectionPlan);
        if (f > 0) {
            return AjaxResult.success("更新成功");
        }
        return AjaxResult.error("更新失败");
    }

    @Override
    public AjaxResult deleteInspectionPlan(Integer id) {
        int i = inspectionPlanDao.deleteById(id.longValue());
        if (i > 0) {
            return AjaxResult.success("删除成功");
        }
        return AjaxResult.error("删除失败");
    }

    @Override
    public AjaxResult findInspectionTask(InspectionTaskBody inspectionTaskBody) {
        List<InspectionTask> result = inspectionTaskDao.findInspectionTask(inspectionTaskBody.getId(), inspectionTaskBody.getNumber(), inspectionTaskBody.getType(), inspectionTaskBody.getName(), inspectionTaskBody.getFlaw(), inspectionTaskBody.getBeginDate(), inspectionTaskBody.getEndDate());
        if (result != null && result.size() > 0) {

            result.stream().forEach(r -> {
                /*r.getRouteLists().stream().forEach(l -> {
                    List<CheckListBody> checkList = inspectionPlanDao.findCheckList(l.getId(), r.getPlanId().intValue());
                    if (!Objects.isNull(checkList)) {
                        l.setCheckList(checkList);
                    }
                });*/
                if (!Objects.isNull(r.getRegular())) {
                    if (r.getRegular() == 0) {
                        r.setRegularName("临时巡检");
                    }
                    if (r.getRegular() == 1) {
                        r.setRegularName("定期巡检");
                    }
                }
                if (!Objects.isNull(r.getRule())) {
                    if (r.getRule() == 1) {
                        r.setRuleName("时");
                    }
                    if (r.getRule() == 2) {
                        r.setRuleName("周");
                    }
                    if (r.getRule() == 3) {
                        r.setRuleName("日");
                    }
                }
            });

            PageInfo pageInfo = new PageInfo<>(result
                                                       .stream()
                                                       .skip((inspectionTaskBody.getCurrPage() - 1) * inspectionTaskBody.getPageSize())
                                                       .limit(inspectionTaskBody.getPageSize())
                                                       .collect(Collectors.toList()));
            return AjaxResult.success(pageInfo);
        }
        return AjaxResult.success(new PageInfo<>(result));
    }

    @Override
    public AjaxResult addInspectionTask(InspectionTask inspectionTask) {
        if (!Objects.isNull(inspectionTask)) {
            SysUser user = SecurityUtils.getLoginUser().getUser();
            inspectionTask.setState(1);
            inspectionTask.setCreatedBy(user.getNickName());
            inspectionTask.setCreateId(user.getUserId());
            int i = inspectionTaskDao.insert(inspectionTask);

            if (!CollectionUtils.isEmpty(inspectionTask.getRouteLists())) {
                for (RouteListBody rou : inspectionTask.getRouteLists()) {
                    if (!Objects.isNull(rou.getCheckList())) {
                        for (CheckListBody che : rou.getCheckList()) {
                            // 根据路线id和计划id删除检查项
                            int del = clockingRouteMiddleDao.deleteByPlanIdAndRouteId(inspectionTask
                                                                                              .getRoutesId()
                                                                                              .intValue(), rou.getId());

                            int sel = clockingRouteCheckDao.findClockingRouteByName(che.getName());
                            // 已存在检查项
                            if (sel > 0) {
                                // 添加检查项关联
                                int add = clockingRouteMiddleDao.insert(new ClockingRouteMiddle(null, rou
                                        .getId()
                                        .longValue(), inspectionTask
                                                                                                        .getRoutesId()
                                                                                                        .longValue(), che.getId(), null, SecurityUtils.getUsername(), null, null));
                            }
                            // 自定义检查项
                            if (sel <= 0) {
                                // 添加自定义检查项
                                ClockingRouteCheck clockingRouteCheck = new ClockingRouteCheck(null, che.getName(), 1, null, SecurityUtils.getUsername(), null, null);
                                clockingRouteCheckDao.insert(clockingRouteCheck);

                                // 添加检查项关联
                                int add = clockingRouteMiddleDao.insert(new ClockingRouteMiddle(null, rou
                                        .getId()
                                        .longValue(), inspectionTask.getRoutesId().longValue(), clockingRouteCheck
                                                                                                        .getId()
                                                                                                        .intValue(), null, SecurityUtils.getUsername(), null, null));
                            }

                        }
                    }
                }


                List<InspectionTaskRouteLog> taskRouteLogs = inspectionTask.getRouteLists().stream().map(body -> {
                    InspectionTaskRouteLog log = new InspectionTaskRouteLog();
                    log.setDeviceId(body.getDeviceId());
                    log.setDeviceName(body.getName());
                    log.setRemark(body.getRemark());
                    log.setRouteId(inspectionTask.getRoutesId());
                    log.setRouteName(inspectionTask.getRoutesName());
                    log.setChecked("1");
                    log.setRouteMiddleId(body.getId());
                    log.setSort(body.getSort());
                    log.setTaskId(inspectionTask.getId());
                    return log;
                }).collect(Collectors.toList());
                inspectionTaskRouteLogMapper.insertBatch(taskRouteLogs);
            }

            if (i > 0) {
                return AjaxResult.success("新增成功");
            }
        }
        return AjaxResult.error("新增失败");
    }

    @Override
    public AjaxResult updateInspectionTask(InspectionTask inspectionTask) {
        if (Objects.isNull(inspectionTask)) {
            return AjaxResult.error("入参为空");
        }


        int i = inspectionTaskDao.update(inspectionTask);
        if (i <= 0) {
            return AjaxResult.error("更新失败");
        }

        if (Objects.nonNull(inspectionTask.getImageUrlList())) {

            ImageUrl imgs = new ImageUrl();
            imgs.setOrderId(inspectionTask.getId());
            imgs.setType(DeviceManageEnums.ImageType.DEVICE_INSPECTION.getCode());
            imgs.setBusType(1);
            imageUrlDao.deleteByOrderIdType(imgs);
            for (ImageUrl imageUrl : inspectionTask.getImageUrlList()) {
                if (!StrUtil.isEmpty(imageUrl.getImgUrl())) {
                    imageUrl.setOrderId(inspectionTask.getId());
                    imageUrl.setType(DeviceManageEnums.ImageType.DEVICE_INSPECTION.getCode());
                    imageUrl.setBusType(1);
                }
            }
            if (!CollectionUtils.isEmpty(inspectionTask.getImageUrlList())) {
                imageUrlDao.insertBatch(inspectionTask.getImageUrlList());
            }
        }

        return AjaxResult.success("更新成功");
    }

    @Override
    public AjaxResult deleteInspectionTask(Integer id) {
        int i = inspectionTaskDao.deleteById(id.longValue());
        if (i > 0) {
            return AjaxResult.success("删除成功");
        }
        return AjaxResult.error("删除失败");
    }

    @Override
    public AjaxResult findInspectionTaskChart(String range) {
        LocalDate begin = LocalDate.now();
        LocalDate end = LocalDate.now();
        String format = "'%Y-%m-%d'";
        List<InspectionTask> inspectionTasks = new ArrayList<>();
        List<ChartBody> result = new ArrayList<>();
        if (range.equals(DAY)) {
            // 本日
            end = end.plusDays(1);
        }
        if (range.equals(WEEK)) {
            // 本周
            begin = begin.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            end = end.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        }
        if (range.equals(MONTH)) {
            // 本月
            // 查询本月能耗单价
            // 设置为本月01号-31号
            begin = begin.plusDays(-begin.getDayOfMonth() + 1);
            end = end.plusDays(-end.getDayOfMonth() + 1).plusMonths(1).plusDays(-1);
        }
        inspectionTasks = inspectionTaskDao.findInspectionTaskByDate(begin.toString(), end.toString(), format);
        result.add(new ChartBody(1, inspectionTasks.stream().filter(i -> i.getState() == 1).count()));
        result.add(new ChartBody(2, inspectionTasks.stream().filter(i -> i.getState() == 2).count()));
        result.add(new ChartBody(3, inspectionTasks.stream().filter(i -> i.getState() == 3).count()));

        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findInspectionFlawChart(String range) {
        LocalDate begin = LocalDate.now();
        LocalDate end = LocalDate.now();
        String format = "'%Y-%m-%d'";
        List<InspectionTask> inspectionTasks = new ArrayList<>();
        List<InspectionPlan> inspectionPlans = new ArrayList<>();
        List<ChartBody> result = new ArrayList<>();
        if (range.equals(DAY)) {
            // 本日
            end = end.plusDays(1);
        }
        if (range.equals(WEEK)) {
            // 本周
            begin = begin.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            end = end.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        }
        if (range.equals(MONTH)) {
            // 本月
            // 查询本月能耗单价
            // 设置为本月01号-31号
            begin = begin.plusDays(-begin.getDayOfMonth() + 1);
            end = end.plusDays(-end.getDayOfMonth() + 1).plusMonths(1).plusDays(-1);
        }
        inspectionTasks = inspectionTaskDao.findInspectionTaskByDate(begin.toString(), end.toString(), format);
        inspectionPlans = inspectionPlanDao.findInspectionPlanByDate(begin.toString(), end.toString(), format);
        // 缺陷个数[type=1]
        result.add(new ChartBody(1, inspectionTasks.stream().mapToLong(InspectionTask::getFlawTotal).sum()));
        // 正常个数[type=2] = 总数 - 缺陷个数
        result.add(new ChartBody(2, inspectionPlans
                .stream()
                .mapToLong(InspectionPlan::getNumber)
                .sum() - inspectionTasks.stream().mapToLong(InspectionTask::getFlawTotal).sum()));

        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findInspectionReportedChart(String range) {
        LocalDate begin = LocalDate.now();
        LocalDate end = LocalDate.now();
        RangeStatistics rangeStatistics = WidgetUtil.findDateByRange(range, begin, end, "%Y-%m-%d", "'%Y-%m-%d'");

        // 上报数 -> 缺陷个数
        List<DateStatistics> inspectionTasks = inspectionTaskDao.findInspectionTaskGroupByDate(rangeStatistics
                                                                                                       .getBegin()
                                                                                                       .toString(), rangeStatistics
                                                                                                       .getEnd()
                                                                                                       .toString(), rangeStatistics.getDatetime());

        Map<String, List<DateStatistics>> result = new LinkedHashMap<>();
        result.put("flaw", WidgetUtil.findDateStatistics(rangeStatistics.getDates(), inspectionTasks));

        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findInspectionCalendar(CalendarBody calendarBody) {

        String dateStr = calendarBody.getDate();
        LocalDate begin = LocalDate.parse(dateStr + "-01");
        LocalDate end = LocalDate.parse(dateStr + "-01");
        end = end.plusDays(-end.getDayOfMonth() + 1).plusMonths(1).plusDays(-1);

        // 上报数 -> 缺陷个数
        List<InspectionTask> inspectionTasks = inspectionTaskDao.findInspectionTaskByDate(begin.toString(), end.toString(), "'%Y-%m-%d'");

        Map<String, List> map = new LinkedHashMap();
        // 日期转换格式
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        // 同日期的存储
        List list3 = new ArrayList();
        for (InspectionTask i : inspectionTasks) {
            Date date = i.getDate();
            if (map.containsKey(formatter.format(date))) {
                list3.add(i);
            } else {
                list3 = new ArrayList();
                list3.add(i);
                map.put(formatter.format(i.getDate()), list3);
            }
        }
        return AjaxResult.success(map);
    }

    @Override
    public AjaxResult findInspectionPlanTemplate() {
        // 定时模板信息
        List<InspectionPlan> result = inspectionPlanDao.findInspectionPlanTemplate();
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.success(result);
    }

    @Override
    public void inspectionCalendarByReport(HttpServletResponse response, CalendarBody calendarBody) {
        String dateStr = calendarBody.getDate();
        LocalDate begin = LocalDate.parse(dateStr + "-01");
        LocalDate end = LocalDate.parse(dateStr + "-01");
        end = end.plusDays(-end.getDayOfMonth() + 1).plusMonths(1).plusDays(-1);
        // 上报数 -> 缺陷个数
        List<InspectionTask> result = inspectionTaskDao.findInspectionTaskByDate(begin.toString(), end.toString(), "'%Y-%m-%d'");
        if (result != null && result.size() > 0) {
            try {
                downloadByInspectionCalendar(InspectionTask.class, result, response);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    private void downloadByInspectionCalendar(Class head, List<InspectionTask> data, HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), head).sheet("模板").doWrite(data);
    }

    @Override
    public AjaxResult findSystemComboBox() {
        List<ComboBoxBody> result = inspectionPlanDao.findSystemComboBox();
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findArtsVisionComboBox() {
        List<ComboBoxBody> result = inspectionPlanDao.findArtsVisionComboBox();
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findCategoryComboBox() {
        List<ComboBoxBody> result = inspectionPlanDao.findCategoryComboBox();
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findGroupComboBox() {
        List<ComboBoxBody> result = inspectionPlanDao.findGroupComboBox();
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findInspectionLine() {
        List<ComboBoxBody> result = inspectionRouteDao
                .findInspectionLine()
                .stream()
                .map(c -> new ComboBoxBody(c.getId().intValue(), c.getName()))
                .collect(Collectors.toList());
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findInspectionCheckByLine(Integer id) {
        // 计划id查询
        List<InspectionPlan> result = inspectionPlanDao.findAllInspectionPlanByRouteId(id);
        if (result != null && result.size() > 0) {
            result.stream().forEach(r -> {
                r.getRouteLists().stream().forEach(l -> {
                    List<CheckListBody> checkList = inspectionPlanDao.findCheckList(l.getId(), r.getId().intValue());
                    l.setCheckList(checkList);
                });
            });
            return AjaxResult.success(result.get(0).getRouteLists());
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findPlanComboBox() {
        List<ComboBoxBody> result = inspectionPlanDao.findPlanComboBox();
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findRouteByDeviceId(Integer deviceId) {
        List<ComboBoxBody> result = inspectionPlanDao.findRouteByDeviceId(deviceId);
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findPlacement() {
        List<ComboBoxBody> result = inspectionPlanDao.findPlacement();
        if (result != null && result.size() > 0) {
            return AjaxResult.success(result);
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findPlacementByUser() {
        DeviceDetail device = new DeviceDetail();
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (user.isAdmin()) {
            List<ComboBoxBody> comboBoxBodies = deviceDetailMapper
                    .newListByDeviceByGroup(device)
                    .stream()
                    .map(d -> new ComboBoxBody(null, d.getPlacement()))
                    .collect(Collectors.toList());
            Set<ComboBoxBody> set = new HashSet<>(comboBoxBodies
                                                          .stream()
                                                          .filter(d -> d.getNumber() != null)
                                                          .collect(Collectors.toList()));
            comboBoxBodies.clear();
            comboBoxBodies.addAll(set);
            return AjaxResult.success(comboBoxBodies);
        }
        device.setTenantId(user.getUserId());
        List<ComboBoxBody> comboBoxBodies = deviceDetailMapper
                .newListByDeviceByGroup(device)
                .stream()
                .map(d -> new ComboBoxBody(null, d.getPlacement()))
                .collect(Collectors.toList());
        Set<ComboBoxBody> set = new HashSet<>(comboBoxBodies);
        comboBoxBodies.clear();
        comboBoxBodies.addAll(set);
        return AjaxResult.success(comboBoxBodies);
    }

    /**
     * 巡检计划定时任务类
     *
     * @author caijinkang
     * @date 2023/4/6 18:12
     */
    public void RyTaskByInspectionPlan() {
        // 定时模板信息
        List<InspectionPlan> result = inspectionPlanDao.findInspectionPlanTemplate();
        if (result != null && result.size() > 0) {
            result.stream().forEach(r -> {
                // 获取规则为：时、周、月的数据，再获取beginDate的时间
                if (r.getRule() == 1) {
                    // 获取这个小时的，生成第二天这个小时的任务
                    InspectionTask task = new InspectionTask();
                    task.setPlanId(r.getId());
                    task.setRule(1);
                    task.setNumber(SerialNumberUtil.createInspectionPlan(DateUtils.nextTomorrow(r.getTimingDate())));
                    task.setName(r.getName());
                    task.setState(1);
                    task.setExecutor(r.getExecutor());
                    task.setTelephone(r.getTelephone());
                    task.setCreatedBy(r.getCreatedBy());
                    task.setBeginDate(DateUtils.nextTomorrow(r.getTimingDate()));
                    task.setEndDate(DateUtils.nextTomorrow(r.getTimingDate()));
                    if (!Objects.isNull(r.getRouteId())) {
                        // 把计划的路线id给任务
                        task.setRoutesId(r.getRouteId());
                    }
                    inspectionTaskDao.insert(task);

                    // 修改时间 timing_date 设置为定时成功的时间
                    InspectionPlan inspectionPlan = new InspectionPlan();
                    inspectionPlan.setId(r.getId());
                    inspectionPlan.setTimingDate(DateUtils.nextTomorrow(r.getTimingDate()));
                    inspectionPlanDao.updateDateById(inspectionPlan);
                }
                if (r.getRule() == 2) {
                    // 获取周几的，生成下周几的任务
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(r.getBeginDate());
                    // 下标从0开始
                    int week = cal.get(Calendar.DAY_OF_WEEK) - 1;
                    if (week == 0) {
                        week = 7;
                    }
                    InspectionTask task = new InspectionTask();
                    task.setPlanId(r.getId());
                    task.setRule(1);
                    task.setNumber(SerialNumberUtil.createInspectionPlan(DateUtils.nextWeak(r.getTimingDate())));
                    task.setName(r.getName());
                    task.setState(1);
                    task.setExecutor(r.getExecutor());
                    task.setTelephone(r.getTelephone());
                    task.setCreatedBy(r.getCreatedBy());
                    task.setBeginDate(DateUtils.nextWeak(r.getTimingDate()));
                    task.setEndDate(DateUtils.nextWeak(r.getTimingDate()));
                    if (!Objects.isNull(r.getRouteId())) {
                        // 把计划的路线id给任务
                        task.setRoutesId(r.getRouteId());
                    }
                    inspectionTaskDao.insert(task);

                    // 修改时间 timing_date 设置为定时成功的时间
                    InspectionPlan inspectionPlan = new InspectionPlan();
                    inspectionPlan.setId(r.getId());
                    inspectionPlan.setTimingDate(DateUtils.nextWeak(r.getTimingDate()));
                    inspectionPlanDao.updateDateById(inspectionPlan);
                }
                if (r.getRule() == 3) {
                    // 获取几月几号的的，生成下个月这号的任务
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(r.getBeginDate());
                    int month = cal.get(Calendar.DAY_OF_MONTH);
                    InspectionTask task = new InspectionTask();
                    task.setPlanId(r.getId());
                    task.setRule(1);
                    task.setNumber(SerialNumberUtil.createInspectionPlan(DateUtils.nextMonth(r.getTimingDate())));
                    task.setName(r.getName());
                    task.setState(1);
                    task.setExecutor(r.getExecutor());
                    task.setTelephone(r.getTelephone());
                    task.setCreatedBy(r.getCreatedBy());
                    task.setBeginDate(DateUtils.nextMonth(r.getTimingDate()));
                    task.setEndDate(DateUtils.nextMonth(r.getTimingDate()));
                    if (!Objects.isNull(r.getRouteId())) {
                        // 把计划的路线id给任务
                        task.setRoutesId(r.getRouteId());
                    }
                    inspectionTaskDao.insert(task);

                    // 修改时间 timing_date 设置为定时成功的时间
                    InspectionPlan inspectionPlan = new InspectionPlan();
                    inspectionPlan.setId(r.getId());
                    inspectionPlan.setTimingDate(DateUtils.nextMonth(r.getTimingDate()));
                    inspectionPlanDao.updateDateById(inspectionPlan);
                }
            });
        }

    }


    @Override
    public List<DeviceDetail> selectDeviceByRoutesId(Long routesId) {
        return inspectionRouteMiddleDao.selectDeviceByRoutesId(routesId);
    }

    @Override
    public InspectionRoute selectInspectionRoutesByRoutesId(Long routesId) {
        return inspectionRouteDao.queryById(routesId);
    }

    @Override
    public InspectionTask selectInspectionTaskById(Long id) {
        InspectionTask task = inspectionTaskDao.queryById(id);
        return task;
    }

    @Override
    public AjaxResult findInspectionTaskRouteLog(Long id) {
        List<InspectionTaskRouteLog> logs = inspectionTaskRouteLogMapper.selectByTaskId(id);
        if (logs.size() != 0) {
            InspectionRoute route = inspectionRouteDao.selectByTaskId(id);
            route.setRouteLogs(logs);
            return AjaxResult.success(route);
        }
        return AjaxResult.error("暂无数据");
    }

    @Override
    public AjaxResult updateInspectionTaskRouteLog(InspectionRoute route) {
        InspectionTaskRouteLogExample ex = new InspectionTaskRouteLogExample();
        ex.createCriteria().andTaskIdEqualTo(route.getTaskId());
        inspectionTaskRouteLogMapper.deleteByExample(ex);

        InspectionTask task = new InspectionTask();
        task.setId(route.getTaskId());
        task.setRoutesId(route.getId());
        inspectionTaskDao.update(task);

        if (route.getRouteList() != null && !route.getRouteList().isEmpty()) {
            List<RouteListBody> list = route.getRouteList();
            List<InspectionTaskRouteLog> logs = list.stream().map(l -> {
                InspectionTaskRouteLog log = new InspectionTaskRouteLog();
                log.setChecked(l.getChecked());
                log.setCheckedTime(l.getCheckedTime());
                log.setDeviceId(l.getDeviceId());
                log.setDeviceName(l.getName());
                log.setPersonId(l.getPersonId());
                log.setProductId(l.getProductId());
                log.setProductName(l.getProductName());
                log.setRouteMiddleId(l.getId());
                log.setSort(l.getSort());
                log.setTaskId(route.getTaskId());
                log.setRouteId(route.getId());
                log.setRouteName(route.getName());
                return log;
            }).collect(Collectors.toList());
            inspectionTaskRouteLogMapper.insertBatch(logs);
        }
        return AjaxResult.success();
    }

    @Override
    public int checkedInspectionTaskItems(Long taskId, String serialNumber) {
        return inspectionTaskRouteLogMapper.checkedInspectionTaskItems(taskId, serialNumber);
    }
}
